package com.gitee.apanlh.util.net.http.handler.body;

import com.gitee.apanlh.exp.HttpBodyParseException;
import com.gitee.apanlh.exp.UnknownTypeException;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.base.StringUtils;
import com.gitee.apanlh.util.net.http.HttpBody;
import com.gitee.apanlh.util.net.http.HttpBodyTypeEnum;
import com.gitee.apanlh.util.net.http.HttpClient;
import com.gitee.apanlh.util.net.http.HttpRequest;
import com.gitee.apanlh.web.http.HttpMethod;

import java.util.EnumMap;
import java.util.Map;

/**
 * 	HttpBody解析，根据请求/响应类型使用不同的解析器
 * 	
 * 	@author Pan
 */
public class HttpBodyParseContext {
	
	/** 枚举MAP */
	private final Map<HttpBodyTypeEnum, HttpBodyParseStrategy> registerMap = new EnumMap<>(HttpBodyTypeEnum.class);
	
	/**		
	 * 	注册解析器
	 * 	
	 * 	@author Pan
	 * 	@param 	bodyType			请求体/响应体类型
	 * 	@param 	bodyParseStrategy	请求体/响应体解析器
	 */
	public void register(HttpBodyParseStrategy bodyParseStrategy, HttpBodyTypeEnum bodyType) {
		registerMap.put(bodyType, bodyParseStrategy);
	}
	
	/**	
	 * 	根据解析器对请求体进行解析
	 * 	<br>自定义请求体/响应体类型枚举
	 * 
	 * 	@author Pan
	 * 	@param 	httpRequest 	请求对象
	 * 	@param 	httpClient 		HTTP客户端
	 * 	@return	HttpRequest
	 * 	@throws HttpBodyParseException	如果body解析失败则抛出此异常
	 */	
	public HttpRequest parse(HttpRequest httpRequest, HttpClient httpClient) throws HttpBodyParseException {
		HttpBody httpBody = httpRequest.getBody();
		//	get默认不执行解析器
		if (httpBody == null && Eq.enums(HttpMethod.GET, httpRequest.getMethod())) {
			return httpRequest;
		}

		HttpBodyTypeEnum bodyType = httpBody.getBodyType();
		HttpBodyParseStrategy strategy = getParse(bodyType);
		
		if (strategy == null) {
			throw new UnknownTypeException(StringUtils.format("unsupported httpBodyType:{}", bodyType));
		}
		return strategy.parse(httpRequest, httpClient);
	}

	/**
	 * 	根据类型获取解析器
	 * 	
	 * 	@author Pan
	 * 	@param 	bodyTypeEnum	HTTP请求体/响应体类型枚举
	 * 	@return	HttpBodyParseStrategy
	 */
	public HttpBodyParseStrategy getParse(HttpBodyTypeEnum bodyTypeEnum) {
		return registerMap.get(bodyTypeEnum);
	}
	
	/**	
	 * 	获取注册解析器MAP
	 * 	
	 * 	@author Pan
	 * 	@return	Map
	 */
	public Map<HttpBodyTypeEnum, HttpBodyParseStrategy> getRegisterMap() {
		return registerMap;
	}
}
